import path from 'path';

import { expect } from '@jest/globals';
import fse from 'fs-extra';

import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility,
  },
};

const testfun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();
  // sync
  const syncCommands = initExecuteCommand({
    mode: 'project',
    product: 'default',
    tasks: '--sync',
  });
  const syncResult = await runHvigorAsync(projectRootPath, syncCommands);
  record.addStep('sync', syncResult);
  expect(syncResult.stdout).toContain('Finished ::init...');

  // 创建buildConfig.json文件
  const entryPath = project.getModule('entry').moduleRootPath();
  const buildConfigPath = path.resolve(entryPath, 'build', 'config', 'buildConfig.json');
  const buildConfig = createBuildConfig(entryPath);
  fse.ensureFileSync(buildConfigPath);
  fse.writeJSONSync(buildConfigPath, buildConfig);
  expect(fse.existsSync(buildConfigPath)).toEqual(true);

  // 执行普通编译构建命令
  const buildCommands = initExecuteCommand({
    mode: 'module',
    product: 'default',
    module: 'entry@default',
    tasks: 'assembleHap',
  });
  const buildResult = await runHvigorAsync(projectRootPath, buildCommands);
  record.addStep('build', buildResult);
  expect(buildResult.stdout).toContain('BUILD SUCCESSFUL');

  // 重新生成热重载模式buildConfig.json
  const reloadBuildConfig = createBuildConfig(entryPath, 'hotReload');
  fse.ensureFileSync(buildConfigPath);
  fse.writeJSONSync(buildConfigPath, reloadBuildConfig);
  expect(fse.existsSync(buildConfigPath)).toEqual(true);

  // 热重载编译构建（编译构建命令和普通编译构建相同）
  const reloadBuildResult = await runHvigorAsync(projectRootPath, buildCommands);
  record.addStep('hotReloadBuild', reloadBuildResult);
  expect(reloadBuildResult.stdout).toContain('BUILD SUCCESSFUL');

  // 查看此时的build/.../loader.json中的patchConfig是否已刷新成上面的reloadBuildConfig
  const loaderJsonPath = path.resolve(entryPath,'build','default','intermediates','loader','default','loader.json');
  expect(fse.existsSync(loaderJsonPath)).toEqual(true);
  const loaderPatchConfig = fse.readJsonSync(loaderJsonPath);
  expect(JSON.stringify(loaderPatchConfig.patchConfig) === JSON.stringify(reloadBuildConfig.patchConfig)).toEqual(true);
};

/**
 * 创建buildConfig.json，普通编译构建和热重载编译构建此文件中的patchConfig属性不同
 * @param modulePath
 * @param buildType
 */
function createBuildConfig(modulePath: string, buildType = 'default') {
  if (buildType === 'hotReload') {
    return {
      patchConfig: {
        enableMap: 'true',
        mode: 'hotReload',
        oldMapFilePath: path.resolve(modulePath, 'build\\default\\intermediates\\loader_out\\default\\ets'),
        changedFileList: path.resolve(modulePath, 'build\\default\\intermediates\\hotReload\\changedFileList.json'),
        removeChangedFileListInSdk: true,
        patchAbcPath: path.resolve(modulePath, 'build\\default\\intermediates\\hotReload\\patchAbcPath'),
      },
    };
  } else {
    return {
      patchConfig: {
        changedFileList: path.resolve(modulePath, 'build\\default\\intermediates\\patch\\default\\changedFileList.json'),
      },
    };
  }
}

TestCaseBuilder.builder()
  .caseName('DTS2024111602330')
  .description(
    '1 创建API14工程；\n' +
      '2 sync；\n' +
      '3 手动创建buildConfig.json文件；\n' +
      '4 执行普通全量构建；\n' +
      '5 手动更改buildConfig.json文件中patchConfig内容；\n' +
      '6 执行热重载构建；\n' +
      '7 查看build/.../loader.json是否刷新；\n',
  )
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.DTS).build())
  .testFun(testfun)
  .load();
